﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace FluentAssertions.Specs.CultureAwareTesting;

public class CulturedXunitTheoryTestCase : XunitTheoryTestCase
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
    public CulturedXunitTheoryTestCase() { }

    /// <summary>
    /// Initializes a new instance of the <see cref="CulturedXunitTheoryTestCase"/> class.
    /// </summary>
    /// <param name="diagnosticMessageSink">The message sink used to send diagnostic messages</param>
    /// <param name="defaultMethodDisplay">Default method display to use (when not customized).</param>
    /// <param name="defaultMethodDisplayOptions">Default method display options to use (when not customized).</param>
    /// <param name="testMethod">The method under test.</param>
    public CulturedXunitTheoryTestCase(IMessageSink diagnosticMessageSink,
        TestMethodDisplay defaultMethodDisplay,
        TestMethodDisplayOptions defaultMethodDisplayOptions,
        ITestMethod testMethod,
        string culture)
        : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod)
    {
        Initialize(culture);
    }

    public string Culture { get; private set; }

    public override void Deserialize(IXunitSerializationInfo data)
    {
        base.Deserialize(data);

        Initialize(data.GetValue<string>("Culture"));
    }

    protected override string GetUniqueID() => $"{base.GetUniqueID()}[{Culture}]";

    private void Initialize(string culture)
    {
        Culture = culture;

        Traits.Add("Culture", culture);

        DisplayName += $"[{culture}]";
    }

    public override Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink,
        IMessageBus messageBus,
        object[] constructorArguments,
        ExceptionAggregator aggregator,
        CancellationTokenSource cancellationTokenSource) =>
        new CulturedXunitTheoryTestCaseRunner(this, DisplayName, SkipReason, constructorArguments, diagnosticMessageSink,
            messageBus, aggregator, cancellationTokenSource).RunAsync();

    public override void Serialize(IXunitSerializationInfo data)
    {
        base.Serialize(data);

        data.AddValue("Culture", Culture);
    }
}
